package ge.lowlevel.js;

 
import ge.engine.Log;
import ge.exceptions.FunctionNonSuported;
import ge.lowlevel.Interval;
import ge.lowlevel.UtilityEngine;
import ge.modules.utils.FileModule;
import ge.modules.utils.IWebCallModule;
import ge.modules.utils.IWebCallModule.WebCallState;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;

import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Timer;
 


public class JSUtilityEngine extends UtilityEngine 
{
	

	public JSUtilityEngine()
	{
		
	}

	@Override
	public void setInterval(int time, final Interval object, boolean loop)
			throws FunctionNonSuported {
		 
		Timer updateTimer = new Timer() {
			@Override
			public void run() {
				object.run();
				
			}
		};
		object.setConcretTimer(updateTimer);
		if(loop)
			updateTimer.scheduleRepeating(time);
		else
			updateTimer.schedule(time);
	}

	@Override
	public void cancelInterval(Interval object) throws FunctionNonSuported {
		 Timer t = (Timer) object.getConcretTimer();
		 t.cancel();
	}
	
	public String formatRequestParams(HashMap<String, String> params)
	{
		StringBuffer postData = new StringBuffer();
		String key;
		Iterator<String> it = params.keySet().iterator();
		
		if(!it.hasNext())
			return "";
		
		//Metemos el primero
		key = it.next();
		
		postData.append(URL.encodeQueryString(key)).append("=").append(URL.encodeQueryString(params.get(key)));
		//Metemos al resto
		while(it.hasNext())
		{
			key = it.next();
			postData.append("&");
			postData.append(URL.encodeQueryString(key)).append("=").append(URL.encodeQueryString(params.get(key)));
			
		}		
		return postData.toString();

	}
	public void callPostUrl(final IWebCallModule callModule)
	{
		RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.POST,callModule.getCall());
		
		try {
			requestBuilder.sendRequest(callModule.getRequestData(), new RequestCallback() {
				
				@Override
				public void onResponseReceived(Request request, Response response) 
				{
					callModule.setState(WebCallState.SENT, response.getText());
					
					Log.write("Respuesta: "+response.getText());
				}
				
				@Override
				public void onError(Request request, Throwable exception) {
					Log.write( "failed call::: "+exception );
					callModule.setState(WebCallState.ERROR, exception.getMessage());
				}
			});
		} catch (RequestException e) {
			callModule.setState(WebCallState.ERROR, e.getMessage());
		}
	}
	@Override
	public String readFile(final FileModule file) 
	{
		  RequestBuilder requestBuilder = new RequestBuilder( RequestBuilder.POST, file.getPath() );
		  
	        try {
	            requestBuilder.sendRequest( null, new RequestCallback(){
	                public void onError(Request  request, Throwable exception) {
	                    Log.write( "failed file reading"+exception );
	                }

	                public void onResponseReceived(Request request, Response response) {
	                    String result=response.getText();
	                    file.setContent(result);

	                }} );
	        } catch ( RequestException e) {
	          Log.write( "failed file reading"+e.getMessage() );
	        }
	        return "";
	}
	//https://developers.google.com/web-toolkit/doc/latest/tutorial/Xsite
	@Override
	public native void remoteCall(int requestId,  IWebCallModule handler)
	/*-{
 		   var callback = "callback"+requestId;//Para el manejador de windows
		   var params =  handler.@ge.modules.utils.IWebCallModule::getRequestData()();
		   var url = handler.@ge.modules.utils.IWebCallModule::getCall()();
		 
		   // [1] Create a script element.
		   var script = document.createElement("script");
		   script.setAttribute("src", url+"?"+params);
		  
		   script.setAttribute("type", "text/javascript");
	
		   // [2] Define the callback function on the window object.
		   window[callback] = function(content) {
		   // [3]
		    
		     handler.@ge.modules.utils.IWebCallModule::setContent(Ljava/lang/String;)(content);
		     window[callback + "done"] = true;
		     
		   }
	
		   // [4] JSON download has 1-second timeout.
		   setTimeout(function() {
			     if (!window[callback + "done"]) {
			    
			       handler.@ge.modules.utils.IWebCallModule::setError(Ljava/lang/String;)("Timeout "+callback);
			     }
		 		
			     // [5] Cleanup. Remove script and callback elements.
			     document.body.removeChild(script);
			     delete window[callback];
			     delete window[callback + "done"];
			}, 200000);
	
		   // [6] Attach the script element to the document body.
		   document.body.appendChild(script);
	  }-*/;
	
	
	@Override 
	public Date	 stringToDate(String format,String date)
	{
		DateTimeFormat dt =  DateTimeFormat.getFormat(format);
		Date d = dt.parse(date);
		return d;
	}
	
	public native void eval_script(String script)
	/*-{
		eval(script);
	}-*/;
	@Override
	public native void execute_script(String source_url)
	/*-{
	 	
		var script = document.createElement("script");
		script.setAttribute("src", source_url);
		content_node = document.createTextNode(content);
		script.appendChild(content_node);
		script.setAttribute("type", "text/javascript");
		$wnd.alert(script.textContent);
		
		document.body.appendChild(script);
	}-*/;
}
